<?php
/**
 * Created by littleU.
 * User: littleU
 * Date: 2021-01-29
 * Time: 13:33
 */

namespace app\api\service;

use app\api\model\Product as ProductModel;
use app\api\model\ProductImage as ProductImageModel;
use app\api\model\ProductSku as ProductSkuModel;
use app\api\model\ProductProperty as ProductPropertyModel;
use app\api\model\ProductSkuStock as ProductSkuStockModel;
use app\api\model\ProductDetail as ProductDetailModel;
use app\api\model\Image as ImageModel;
use app\api\model\AppletModuleSku as AppletModuleSkuModel;
use think\Db;
use think\Exception;


class Product extends BaseService
{
    public function getProductByCondition($data)
    {
        $condition = [];
        $page = isset($data['page']) ? $data['page'] : $this->page;
        $limit = isset($data['limit']) ? $data['limit'] : $this->limit;
        $order = isset($data['order']) ? $data['order'] : $this->order;
        if (isset($data['status'])) {
            $condition['status'] = $data['status'];
        }
        if (isset($data['name'])) {
            $condition['name'] = ['like', '%' . $data['name'] . '%'];
        }
        if (isset($data['code'])) {
            $condition['code'] = $data['code'];
        }
        $result = (new ProductModel())->with(['mainImg' => function($query){
            $query->with('imgUrl');
        },'category', 'sku' => function($query1){
            $query1->with(['skuSales','stock']);
        }, 'property', 'detailContent'])->where($condition)->order($order)->page($page)->limit($limit)->select();
        $count = (new ProductModel())->where($condition)->count();

        return json([
            'code' => config('code.success'),
            'msg' => '请求成功',
            'data' => $result,
            'count' => $count
        ]);
    }

    public static function getSkuByCode($code)
    {
//        $skus = ProductSkuModel::with('stock')->where('item_code',$code)->select();
        $skus = (new ProductSkuModel())->with('stock')->where('item_code',$code)->select();
        $count = (new ProductSkuModel())->where('item_code',$code)->count();
        return json([
            'code' => config('code.success'),
            'count' => $count,
            'data' => $skus
        ]);
    }

    public static function getPropertyByCode($code)
    {
        $properties = (new ProductPropertyModel())->where('item_code',$code)->select();
        $count = (new ProductPropertyModel())->where('item_code',$code)->count();
        return json([
            'code' => config('code.success'),
            'count' => $count,
            'data' => $properties
        ]);
    }

    public function setProduct($product)
    {
        if(isset($product['product_appendix']))
        {
            $product['product_appendix'] = implode(',',$product['product_appendix']);
        }
        else
        {
            $product['product_appendix'] = null;
        }
        $id = $product['id'];
        if ($id == '') {
            return $this->createProduct($product);
        } else {
            return $this->editProduct($product, $id);
        }
    }

    public static function setProductStatus($data)
    {
        try
        {
            $obj = new ProductModel();
            $obj->allowField(true)->save($data, ['id' => $data['id']]);
        }
        catch (\Exception $ex)
        {
            return json([
                'code' => config('code.error'),
                'msg' => $ex->getMessage()
            ]);
        }
        if($data['item_code'])
        {
            $del = $data['del'];
            if($del == 1)
            {
                //删除，同时下架模块商品
                $appletModuleSkuArr = (new AppletModuleSkuModel())->where('item_code',$data['item_code'])->select();
                foreach($appletModuleSkuArr as $obj)
                {
                    $obj->status = -1;
                    $obj->save();
                }
                $productSkuArr = (new ProductSkuModel)->where('item_code',$data['item_code'])->select();
                foreach($productSkuArr as $productSku)
                {
                    $productSku->sku_status = -1;
                    $productSku->save();
                }
            }
            else if($del == 0)
            {
                $productSkuArr = (new ProductSkuModel)->where('item_code',$data['item_code'])->select();
                foreach($productSkuArr as $productSku)
                {
                    $productSku->sku_status = 1;
                    $productSku->save();
                }
            }
        }
        return json(['code'=> config('code.success'),'msg' => '状态更改成功']);
    }

    public static function setProductSku($data)
    {
        try
        {
            $obj = new ProductSkuModel();
            $obj->allowField(true)->save($data, ['id' => $data['id']]);
        }
        catch (\Exception $ex)
        {
            return json([
                'code' => config('code.error'),
                'msg' => $ex->getMessage()
            ]);
        }
        return json([
            'code' => config('code.success'),
            'msg' => '操作成功'
        ]);
    }

    public static function setProductSkuStock($data)
    {
        try
        {
            $stockObj = (new ProductSkuStockModel())->where('sku_code', $data['sku_code'])->find();
            if($stockObj)
            {
                $stockObj->salable_qty = $data['salable_qty'];
                $stockObj->allowField(true)->save();
            }
            else
            {
                $newStockObj = new ProductSkuStockModel();
                $newStockObj->item_code = $data['item_code'];
                $newStockObj->sku_code = $data['sku_code'];
                $newStockObj->salable_qty = $data['salable_qty'];
                $newStockObj->save();
            }
        }
        catch(\Exception $ex)
        {
            return json([
                'code' => config('code.error'),
                'msg' => $ex->getMessage()
            ]);
        }
        return json([
            'code' => config('code.success'),
            'msg' => '库存设置成功'
        ]);
    }

    public static function setProductProperty($data)
    {
        $type = $data['type'];
        $code = $data['code'];
        if($type == 'add')
        {
            //新增属性
            $propertyArr = [];
            for($i=0; $i<count($data['name']);$i++)
            {
                $tmpArr = [];
                $tmpArr['name'] = $data['name'][$i];
                $tmpArr['detail'] = $data['detail'][$i];
                $tmpArr['item_code'] = $code;
                array_push($propertyArr, $tmpArr);
            }
            try
            {
                $propertyObj = new ProductPropertyModel();
                $propertyObj->saveAll($propertyArr);
            }
            catch(\Exception $ex)
            {
                return json([
                    'code' => config('code.error'),
                    'msg' => $ex->getMessage()
                ]);
            }
        }
        else
        {
            //编辑属性
            for($i=0; $i<count($data['name']);$i++)
            {
                if($data['id'][$i] == '')
                {
                    try
                    {
                        $obj = new ProductPropertyModel();
                        $obj->item_code = $code;
                        $obj->name = $data['name'][$i];
                        $obj->detail = $data['detail'][$i];
                        $obj->save();
                    }
                    catch(\Exception $ex)
                    {
                        return json([
                            'code' => config('code.error'),
                            'msg' => $ex->getMessage()
                        ]);
                    }
                }
                else
                {
                    try
                    {
                        $obj = ProductPropertyModel::get($data['id'][$i]);
                        $obj->name = $data['name'][$i];
                        $obj->detail = $data['detail'][$i];
                        $obj->save();
                    }
                    catch(\Exception $ex)
                    {
                        return json([
                            'code' => config('code.error'),
                            'msg' => $ex->getMessage()
                        ]);
                    }
                }
            }
        }
        return json([
            'code' => config('code.success'),
            'msg' => '商品属性编辑成功'
        ]);
    }

    private function createProduct($product)
    {
        $barcodeArr = $product['sku_barcode'];
        $resultArr = (new ProductSkuModel())->where('sku_barcode','in',$barcodeArr)->column('sku_barcode');
        if(count($resultArr) > 0)
        {
            return json([
                'code' => config('code.error'),
                'msg'  => implode(",",$resultArr).'：已存在的条码'
            ]);
        }
        else
        {
            $code = $this->getProductCode(8);
            $product['code'] = $code;
            Db::startTrans();
            try
            {
                $id = (new ProductModel())->add($product);
                Db::commit();
            }
            catch(Exception $ex)
            {
                Db::rollback();
                return json([
                    'code' => config('code.error'),
                    'msg' => $ex->getMessage()
                ]);
            }
            $this->saveSku($product, $code);
            $this->saveImage($product, $id);
            $this->saveDetail($product, $id);
            return json([
                'code' => config('code.success'),
                'msg'  => 'id为：' . $id . '的商品操作成功'
            ]);
        }
    }


    private function editProduct($product, $id)
    {
        $resultArr = [];
        for($j=0; $j<count($product['sku_barcode']); $j++)
        {
            $obj = (new ProductSkuModel())->where('sku_barcode',$product['sku_barcode'][$j])->find();
            if($obj && $obj->sku_code != $product['sku_code'][$j])
            {
                array_push($resultArr, $product['sku_barcode'][$j]);
            }
        }


        if(count($resultArr) > 0)
        {
            return json([
                'code' => config('code.error'),
                'msg'  => implode(",",$resultArr).'：已存在的条码'
            ]);
        }
        else
        {
            Db::startTrans();
            try
            {
                $productObj = new ProductModel();
                $productObj->allowField(true)->save($product, ['id' => $id]);
                Db::commit();
            }
            catch(Exception $ex)
            {
                Db::rollback();
                return json([
                    'code' => config('code.error'),
                    'msg' => $ex->getMessage()
                ]);
            }
            $this->editSku($product);
            $this->saveImage($product, $id);
            $this->editDetail($product, $id);
            return json([
                'code' => config('code.success'),
                'msg'  => 'id为：' . $id . '的商品操作成功'
            ]);
        }
    }

    //保存sku
    private function saveSku($product, $code)
    {
        $skuArr = [];
        $stockArr = [];
        for($i=0; $i < count($product['sku_name']);$i++)
        {
            $tempArr = [];
            $stockTempArr = [];
            $skuCode = $this->getProductCode(11);
            $tempArr['item_code'] = $code;
            $tempArr['sku_code'] = $skuCode;
            $tempArr['sku_name'] = $product['sku_name'][$i];
            $tempArr['sku_weight'] = $product['sku_weight'][$i];
            $tempArr['sku_sales_price'] = $product['sku_price'][$i];
            $tempArr['sku_barcode'] = $product['sku_barcode'][$i];
//            $tempArr['limit_number'] = $product['limit_number'][$i] == ''?null:$product['limit_number'][$i];
            $stockTempArr['item_code'] = $code;
            $stockTempArr['sku_code'] = $skuCode;
            $stockTempArr['salable_qty'] = $product['sku_stock'][$i];
            array_push($skuArr, $tempArr);
            array_push($stockArr, $stockTempArr);
        }

        Db::startTrans();
        try
        {
            $skuObj = new ProductSkuModel();
            $skuObj->saveAll($skuArr);
            $stockObj = new ProductSkuStockModel();
            $stockObj->saveAll($stockArr);
            Db::commit();
        }
        catch(Exception $ex)
        {
            Db::rollback();
            return json([
                'code' => config('code.error'),
                'msg' => $ex->getMessage()
            ]);
        }
    }


    private function editSku($product)
    {
        $code = $product['code'];

        $skuArr = [];
        $stockArr = [];
        for($i=0; $i < count($product['sku_name']);$i++)
        {
            $tmpSku = (new ProductSkuModel())->where('sku_code',$product['sku_code'][$i])->where('sku_status',1)->find();

            if($tmpSku)
            {
                //修改
                $tmpSku->sku_name = $product['sku_name'][$i];
                $tmpSku->sku_weight = $product['sku_weight'][$i];
                $tmpSku->sku_sales_price = $product['sku_price'][$i];
//                $tmpSku->limit_number = $product['limit_number'][$i]==''?null:$product['limit_number'][$i];
                $tmpSku->sku_barcode = $product['sku_barcode'][$i];
                $tmpSku->save();
                $tmpStock = (new ProductSkuStockModel())->where('sku_code',$product['sku_code'][$i])->where('stock_status',1)->find();
                if(!$tmpStock)
                {
                    $obj = new ProductSkuStockModel();
                    $obj->item_code = $code;
                    $obj->sku_code = $product['sku_code'][$i];
                    $obj->salable_qty = $product['sku_stock'][$i];
                    $obj->save();
                }
                else
                {
                    $tmpStock->salable_qty = $product['sku_stock'][$i];
                    $tmpStock->save();
                }

            }
            else
            {
                //添加
                $tempArr = [];
                $stockTempArr = [];
                $skuCode = $this->getProductCode(11);
                $tempArr['item_code'] = $code;
                $tempArr['sku_code'] = $skuCode;
                $tempArr['sku_name'] = $product['sku_name'][$i];
                $tempArr['sku_weight'] = $product['sku_weight'][$i];
                $tempArr['sku_barcode'] = $product['sku_barcode'][$i];
                $tempArr['sku_sales_price'] = $product['sku_price'][$i];
//                $tempArr['limit_number'] = $product['limit_number'][$i] == ''?null:$product['limit_number'][$i];
                $stockTempArr['item_code'] = $code;
                $stockTempArr['sku_code'] = $skuCode;
                $stockTempArr['salable_qty'] = $product['sku_stock'][$i];
                array_push($skuArr, $tempArr);
                array_push($stockArr, $stockTempArr);
            }
        }

        if(count($skuArr) >0)
        {
            Db::startTrans();
            try
            {
                $skuObj = new ProductSkuModel();
                $skuObj->saveAll($skuArr);
                $stockObj = new ProductSkuStockModel();
                $stockObj->saveAll($stockArr);
                Db::commit();
            }
            catch(Exception $ex)
            {
                Db::rollback();
                return json([
                    'code' => config('code.error'),
                    'msg' => $ex->getMessage()
                ]);
            }
        }
    }

    private function saveImage($product, $id)
    {
        $imgIds = [];
        $datas = [];
        $imageData = [
            'url' => '',
            'from' => 1
        ];
        if(isset($product['src']) && !empty($product['src']))
        {
            foreach($product['src'] as $src)
            {
                $imageData['url'] = $src;
                array_push($datas, $imageData);
            }
        }

        Db::startTrans();
        try
        {
            $imgObj = new ImageModel();
            $result = $imgObj->saveAll($datas);
            Db::commit();
        }
        catch(Exception $ex)
        {
            Db::rollback();
            return json([
                'code' => config('code.error'),
                'msg' => $ex->getMessage(),
                'data' => ''
            ]);
        }
        $tmpData = [
            'product_id' => $id,
            'img_id' => '',
            'type' => 1,
            'order' => 0,
        ];
        foreach($result as $k => $v)
        {
            $tmpData['order'] = $k;
            $tmpData['img_id'] = $v->id;

            array_push($imgIds, $tmpData);
        }
        try
        {
            $productImageObj = new ProductImageModel();

            $productImageObj->saveAll($imgIds);
        }
        catch(Exception $ex)
        {
            throw new ProductException([
                'msg' => $ex->getMessage(),
                'errorCode' => 80001
            ]);
        }
    }

    private function saveDetail($product, $id)
    {
        if(isset($product['detail']) && !empty($product['detail']))
        {
            try
            {
                $productDetailObj = new ProductDetailModel();
                $productDetailObj->detail = $product['detail'];
                $productDetailObj->product_id = $id;
                $productDetailObj->save();
            }
            catch(Exception $ex)
            {
                throw new ProductException([
                    'msg' => $ex->getMessage(),
                    'errorCode' => 80002
                ]);
            }
        }
    }


    private function editDetail($product, $id)
    {
        if(isset($product['detail']) && !empty($product['detail']))
        {
            try
            {
                $productDetailObj = ProductDetailModel::where('product_id', $id)->find();
                $productDetailObj->detail = $product['detail'];
                $productDetailObj->save();
            }
            catch(Exception $ex)
            {
                throw new ProductException([
                    'msg' => $ex->getMessage(),
                    'errorCode' => 80002
                ]);
            }
        }
    }
    private function getProductCode($len)
    {
        $chars = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k","l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v","w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G","H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R","S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2","3", "4", "5", "6", "7", "8", "9" ];
        $charsLen = count($chars) - 1;
        shuffle($chars);                            //打乱数组顺序
        $str = '';
        for($i=0; $i<$len; $i++)
        {
            $str .= $chars[mt_rand(0, $charsLen)]; //随机取出一位
        }
        return $str;
    }
}